﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace C1
{
    
    //定义观察者接口
    public interface IObserver
    {
        void Update(Subject subject);
    }

    //定义被观察者基类/抽象类
    public abstract class Subject
    {
        private List<IObserver> observers = new List<IObserver>();
        private readonly object ob_lock = new object();

        public void Attach(IObserver observer)
        {
            lock(ob_lock)
            {
                observers.Add(observer);
            }   
        }
        public void Detach(IObserver observer)
        {
            lock(ob_lock)
            {
                observers.Remove(observer);
            }
        }
        public void Notify()
        {
            List<IObserver> co_observers;
            lock(ob_lock)
            {
                co_observers = new List<IObserver>(observers);
            }
            foreach(var observer in co_observers)
            {
                observer.Update(this);
            }
        }
    }
    //定义具体的被观察者类：猫
    public class Cat : Subject
    {
        public void SetAction(string action)
        {
            if (action == "喵")
            {
                Console.WriteLine("猫叫了：{0}",action);
                Notify();
            }
        }
    }
    //定义具体的观察者类：老鼠，人
    public class Mouse:IObserver
    {
        public void Update(Subject subject)
        {
            if(subject is Cat)
            {
                Console.WriteLine("老鼠吓跑了");
            }
        }
    }
    public class Person : IObserver
    {
        public void Update(Subject subject)
        {
            if (subject is Cat)
            {
                Console.WriteLine("人醒了");
            }
        }
    }
    //测试
    class Program
    {
        static void Main()
        {
            var cat = new Cat();
            var mouse = new Mouse();
            var person = new Person();

            cat.Attach(mouse);
            cat.Attach(person);

            cat.SetAction("喵");
        }
    }
}
